<template>
  <vxe-toolbar>
    <template #buttons>
      <a-button :disabled="disabledBatchSetting" size="small" @click="handleOpenBatchSettingModal">批量设置</a-button>
    </template>
  </vxe-toolbar>

  <JVxeTable
    ref="tableRef"
    stripe
    keepSource
    rowSelection
    :toolbarConfig="toolbarConfig"
    :auto-resize="true"
    :maxHeight="400"
    :checkboxConfig="{ range: true }"
    :disabledRows="{ isPk: [true] }"
    :disabled="false"
    :columns="tableColums"
    :dataSource="skuData"
    @select-row-change="handleSelectRowChange"
  >
    <template #stockSlot="{ row }">
      <a-button v-if="!isUpdate || getStoreStockTotal(row) === 0" type="link" class="mgt-stock" @click="handleOpenStoreStock(row)">管理库存</a-button>
      <span v-else class="mgt-stock-number">{{ getStoreStockTotal(row) }}</span>
    </template>
  </JVxeTable>
  <SkuStockSettingModel @register="registerBatchSettingModal" @success="handleBatchSettingSku" />
  <MgtSkuStockModal @register="registerMgtSkuStockModal" @success="handleUpdateStock" />
</template>
<script lang="ts" name="shop-goods-sku-stock" setup>
  import { ref, onMounted, watch, computed, unref } from "vue"
  import { skuStockColumns } from "./goods.data"
  import { propTypes } from "/@/utils/propTypes"
  import { VxeGridInstance } from "vxe-table"
  import { JVxeTypes, JVxeColumn } from "/@/components/jeecg/JVxeTable/types"
  import { useModal } from "/@/components/Modal"
  import MgtSkuStockModal from "./MgtSkuStockModal.vue"
  import SkuStockSettingModel from "./SkuStockSettingModel.vue"
  import { randomString } from "/@/utils/common/compUtils"
  const [registerBatchSettingModal, { openModal: openBatchSettingModal }] = useModal()
  const [registerMgtSkuStockModal, { openModal: openMgtSkuStockModal }] = useModal()
  const toolbarConfig = ref({
    btns: [],
  })
  interface SkuData {
    id: string
    tempId: string // 随机生成
    stockList: string
    weight: string
    price: string
  }
  // key=规格id
  const addColumns = ref<Map<string, JVxeColumn>>(new Map())
  const dataSource = ref<Map<string, any>>(new Map())
  const disabledBatchSetting = ref<boolean>(true)
  const isInit = ref(false)
  const props = defineProps({
    value: propTypes.array.def([]),
    // 选择的规格
    selectSpecList: propTypes.array.def([]),
    // 是否更新
    isUpdate: propTypes.bool.def(false),
  })
  const tableRef = ref<VxeGridInstance>()
  const skuData = ref<SkuData[]>([])

  const tableColums = computed(() => {
    let columns = Array.from(addColumns.value.values())
    columns = columns ? columns : []
    skuStockColumns.forEach((e) => columns.push(e))
    return columns
  })
  const emit = defineEmits(["register", "update:value"])
  onMounted(() => {
    if (props.selectSpecList) {
      processSkuStockColumns(props.selectSpecList)
      processSkuStockData(props.selectSpecList)
    }
  })

  watch(
    () => props.selectSpecList,
    (selectSpecList: any) => {
      processSkuStockColumns(selectSpecList)
      processSkuStockData(selectSpecList)
    },
    { deep: true }
  )

  /**
   * 处理sku库存的表列字段
   * @param selectSpec 选择的规格
   */
  const processSkuStockColumns = (newSelectSpecList) => {
    console.log("newSelectSpecList", newSelectSpecList)
    const columns: JVxeColumn[] = []
    if (newSelectSpecList?.length === 0) {
      console.log("selectValue length is 0")
      addColumns.value.clear()
    } else {
      const deleteColumnSet: Set<string> = new Set()
      Array.from(addColumns.value.keys()).forEach((e) => deleteColumnSet.add(e))
      newSelectSpecList.filter((e) => e.specId && e.specId !== "" && e.values.length > 0).forEach((e) => deleteColumnSet.delete(e.specId))

      const addColumnSet: Set<string> = new Set()
      newSelectSpecList.filter((e) => e.specId && e.specId !== "" && e.values.length > 0).forEach((e) => addColumnSet.add(e.specId))
      Array.from(addColumns.value.keys()).forEach((e) => addColumnSet.delete(e))

      const tempMap = new Map()
      newSelectSpecList.forEach((e) => tempMap.set(e.specId, e))

      deleteColumnSet.forEach((e) => addColumns.value.delete(e))
      addColumnSet.forEach((specId) => {
        const spec = tempMap.get(specId)
        addColumns.value.set(spec.specId, {
          title: spec.name,
          key: "sku_" + spec.specId,
          type: JVxeTypes.normal,
          width: 80,
        })
      })
    }

    Array.from(addColumns.value.values()).forEach((e) => columns.push(e))
    skuStockColumns.forEach((e) => columns.push(e))
  }

  /**
   * 处理sku库存的表数据
   * @param selectSpec 选择的规格
   */
  const processSkuStockData = async (newSelectSpecList) => {
    dataSource.value.clear()
    newSelectSpecList.filter((e) => e.specId !== "").forEach((e) => dataSource.value.set(e.specId, e))

    let arr: any = []
    Array.from(dataSource.value.values()).forEach((spec) => {
      const data = spec.values.map((value) => ({ ...spec, value }))
      if (data.length > 0) {
        arr.push(data)
      }
    })

    let temp: any = []
    let resList: any[] = []
    /**
     * 【全排列算法】
     */
    let arrange = (arr, index = 0) => {
      if (arr.length === 0) {
        return
      }
      arr[index].forEach((item) => {
        temp[index] = item
        index + 1 < arr.length ? arrange(arr, index + 1) : resList.push(temp.slice())
      })
    }
    arrange(arr)

    skuData.value = resList.map((e) => {
      const data: any = {}
      data.tempId = randomString(16)
      const specData: any[] = []
      e.forEach((spec) => {
        specData.push({
          key: spec.name,
          value: spec.value,
          specId: spec.specId,
        })
        ;(data["sku_" + spec.specId] = spec.value),
          (data["weight"] = "0.00"),
          (data["price"] = "0.00"),
          (data["costPrice"] = "0.00"),
          (data["stockAlarm"] = "0"),
          (data["stockList"] = [])
      })
      data["specData"] = specData
      return data
    })

    // 将传递的进来的数据转成map
    if (!isInit.value) {
      const oldVal: any[] = props.value || []
      const propsSkuMap: Map<any, any> = new Map()
      oldVal.forEach((e) =>
        propsSkuMap.set(
          e.specData
            .map((e1) => e1.value)
            .sort()
            .join("_"),
          e
        )
      )

      const compSkuMap: Map<any, any> = new Map()
      skuData.value.forEach((e) => compSkuMap.set(getCompSkuMapKey(e), e))

      const newSkuData: any[] = []
      // 遍历外部传递的sku数据
      propsSkuMap.forEach((e) => {
        const key = e.specData
          .map((e1) => e1.value)
          .sort()
          .join("_")
        newSkuData.push({ ...compSkuMap.get(key), ...e })
      })

      if (newSkuData.length !== 0) {
        skuData.value = newSkuData
        console.log("newSkuData", newSkuData)
      }
      isInit.value = true
    }

    emit("update:value", unref(skuData))
  }

  const getCompSkuMapKey = (skuData: any[]) => {
    const resp: any[] = []
    for (const key in skuData) {
      if (key.includes("sku_")) {
        resp.push(skuData[key])
      }
    }
    return resp.sort().join("_")
  }

  const handleSelectRowChange = ({ selectedRows }) => {
    disabledBatchSetting.value = selectedRows.length === 0
  }

  const handleOpenBatchSettingModal = () => {
    openBatchSettingModal(true, {})
  }

  /**
   * 批量设置sku
   * @param values
   */
  const handleBatchSettingSku = (values) => {
    console.log("values", values)
    const selectedData = new Map()
    tableRef.value?.getSelectedData().forEach((e) => selectedData.set(e.tempId, e))
    console.log("selectedData", selectedData, "skuData", skuData.value)

    skuData.value = skuData.value.map((e) => {
      if (selectedData.has(e.tempId)) {
        return { ...e, ...values }
      }
      return e
    })
    emit("update:value", unref(skuData))
  }

  /**
   * 更新库存信息
   */
  const handleUpdateStock = (tempId, value) => {
    skuData.value = skuData.value.map((e) => {
      if (e.tempId === tempId) {
        return { ...e, stockList: value }
      }
      return e
    })
    emit("update:value", unref(skuData))
  }

  const handleOpenStoreStock = (record) => {
    openMgtSkuStockModal(true, { record })
  }

  /**
   * 获取库存总数
   * @param record
   */
  const getStoreStockTotal = (record) => {
    let totalStock = 0
    record?.stockList.forEach((e) => (totalStock += e.stock))
    return totalStock
  }

  const getSkuStock = () => {
    const skuList = tableRef.value?.getTableData() as any[]
    console.log("skuData", skuList)
    for (const sku of skuList) {
      if (sku.id.startsWith("row_")) {
        sku.id = undefined
      }
    }
    emit("update:value", skuList)
    return skuList
  }
  defineExpose({
    getSkuStock,
  })
</script>

<style lang="less">
  .mgt-stock {
    margin-left: -15px;
  }
  .mgt-stock-number {
    margin-left: 5px;
  }
</style>
